acm: Fix the traversal of the event channel buckets and use the active
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 1 Mar 2007 13:45:53 +0000 (13:45 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 1 Mar 2007 13:45:53 +0000 (13:45 +0000)
grant table entries instead of the shared ones. I had to move some
functions from grant_table.c into grant_table.h to make them usable by
the ACM module.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
xen/acm/acm_simple_type_enforcement_hooks.c
xen/common/grant_table.c
xen/include/xen/grant_table.h

index 8b83fcf4bf98afa7ff80efb40bd4c9582160e6d8..f5793a22d85235551197e393a86a141c61665132 100644 (file)
@@ -177,7 +177,7 @@ ste_init_state(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs)
     ssidref_t ste_ssidref, ste_rssidref;
     struct domain *d, *rdom;
     domid_t rdomid;
-    struct grant_entry sha_copy;
+    struct active_grant_entry *act;
     int port, i;
 
     rcu_read_lock(&domlist_read_lock);
@@ -185,64 +185,75 @@ ste_init_state(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs)
     /* go through all domains and adjust policy as if this domain was started now */
     for_each_domain ( d )
     {
+        struct evtchn *ports;
+        unsigned int bucket;
         ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
                              (struct acm_ssid_domain *)d->ssid);
         ste_ssidref = ste_ssid->ste_ssidref;
         traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n",
                     __func__, d->domain_id, ste_ssidref);
         /* a) check for event channel conflicts */
-        for (port=0; port < NR_EVTCHN_BUCKETS; port++) {
+        for (bucket = 0; bucket < NR_EVTCHN_BUCKETS; bucket++) {
             spin_lock(&d->evtchn_lock);
-            if (d->evtchn[port] == NULL ||
-                d->evtchn[port]->state == ECS_UNBOUND) {
+            ports = d->evtchn[bucket];
+            if (ports == NULL) {
                 spin_unlock(&d->evtchn_lock);
-                continue;
+                break;
             }
-            if (d->evtchn[port]->state == ECS_INTERDOMAIN) {
-                rdom = d->evtchn[port]->u.interdomain.remote_dom;
-                rdomid = rdom->domain_id;
-            } else {
-                spin_unlock(&d->evtchn_lock);
-                continue; /* port unused */
-            }
-            spin_unlock(&d->evtchn_lock);
 
-            /* rdom now has remote domain */
-            ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
-                                  (struct acm_ssid_domain *)(rdom->ssid));
-            ste_rssidref = ste_rssid->ste_ssidref;
-            traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", 
-                        __func__, d->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port);  
-            /* check whether on subj->ssid, obj->ssid share a common type*/
-            if (!have_common_type(ste_ssidref, ste_rssidref)) {
-                printkd("%s: Policy violation in event channel domain %x -> domain %x.\n",
-                        __func__, d->domain_id, rdomid);
-                goto out;
+            for (port=0; port < EVTCHNS_PER_BUCKET; port++) {
+                if (ports[port].state == ECS_INTERDOMAIN) {
+                    rdom = ports[port].u.interdomain.remote_dom;
+                    rdomid = rdom->domain_id;
+                } else {
+                    continue; /* port unused */
+                }
+
+                /* rdom now has remote domain */
+                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
+                                      (struct acm_ssid_domain *)(rdom->ssid));
+                ste_rssidref = ste_rssid->ste_ssidref;
+                traceprintk("%s: eventch: domain %x (ssidref %x) --> "
+                            "domain %x (rssidref %x) used (port %x).\n",
+                            __func__, d->domain_id, ste_ssidref,
+                            rdom->domain_id, ste_rssidref, port);
+                /* check whether on subj->ssid, obj->ssid share a common type*/
+                if (!have_common_type(ste_ssidref, ste_rssidref)) {
+                    printkd("%s: Policy violation in event channel domain "
+                            "%x -> domain %x.\n",
+                            __func__, d->domain_id, rdomid);
+                    spin_unlock(&d->evtchn_lock);
+                    goto out;
+                }
             }
+            spin_unlock(&d->evtchn_lock);
         } 
+
         /* b) check for grant table conflicts on shared pages */
         spin_lock(&d->grant_table->lock);
-        for ( i = 0; i < nr_grant_entries(d->grant_table); i++ ) {
-#define SPP (PAGE_SIZE / sizeof(struct grant_entry))
-            sha_copy = d->grant_table->shared[i/SPP][i%SPP];
-            if ( sha_copy.flags ) {
-                printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n",
-                        __func__, d->domain_id, i, sha_copy.flags, sha_copy.domid, 
-                        (unsigned long)sha_copy.frame);
-                rdomid = sha_copy.domid;
+        for ( i = 0; i < nr_active_grant_frames(d->grant_table); i++ ) {
+#define APP (PAGE_SIZE / sizeof(struct active_grant_entry))
+            act = &d->grant_table->active[i/APP][i%APP];
+            if ( act->pin != 0 ) {
+                printkd("%s: grant dom (%hu) SHARED (%d) pin (%d)  "
+                        "dom:(%hu) frame:(%lx)\n",
+                        __func__, d->domain_id, i, act->pin,
+                        act->domid, (unsigned long)act->frame);
+                rdomid = act->domid;
                 if ((rdom = rcu_lock_domain_by_id(rdomid)) == NULL) {
                     spin_unlock(&d->grant_table->lock);
                     printkd("%s: domain not found ERROR!\n", __func__);
                     goto out;
-                };
+                }
                 /* rdom now has remote domain */
-                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, 
+                ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
                                       (struct acm_ssid_domain *)(rdom->ssid));
                 ste_rssidref = ste_rssid->ste_ssidref;
                 rcu_unlock_domain(rdom);
                 if (!have_common_type(ste_ssidref, ste_rssidref)) {
                     spin_unlock(&d->grant_table->lock);
-                    printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n",
+                    printkd("%s: Policy violation in grant table "
+                            "sharing domain %x -> domain %x.\n",
                             __func__, d->domain_id, rdomid);
                     goto out;
                 }
index 68d1fa2d8cada90dca2d3a7a50eced8ad998372d..642a3af4a9a6d7887d8adc2bd099296aa6d69dc5 100644 (file)
@@ -78,27 +78,6 @@ static unsigned inline int max_nr_maptrack_frames(void)
     return (max_nr_grant_frames * MAX_MAPTRACK_TO_GRANTS_RATIO);
 }
 
-static inline unsigned int
-num_act_frames_from_sha_frames(const unsigned int num)
-{
-    /* How many frames are needed for the active grant table,
-     * given the size of the shared grant table?
-     *
-     * act_per_page = PAGE_SIZE / sizeof(active_grant_entry_t);
-     * sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
-     * num_sha_entries = num * sha_per_page;
-     * num_act_frames = (num_sha_entries + (act_per_page-1)) / act_per_page;
-     */
-    return ((num * (PAGE_SIZE / sizeof(grant_entry_t))) +
-            ((PAGE_SIZE / sizeof(struct active_grant_entry))-1))
-           / (PAGE_SIZE / sizeof(struct active_grant_entry));
-}
-
-static inline unsigned int
-nr_active_grant_frames(struct grant_table *gt)
-{
-    return num_act_frames_from_sha_frames(nr_grant_frames(gt));
-}
 
 #define SHGNT_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_t))
 #define shared_entry(t, e) \
index 54ea021683bb1261ba8fb8427ce25af6d69c50ac..5ae9149bc1eed979e85cdfad60501552237ce931 100644 (file)
@@ -120,4 +120,26 @@ static inline unsigned int nr_grant_entries(struct grant_table *gt)
     return (nr_grant_frames(gt) << PAGE_SHIFT) / sizeof(grant_entry_t);
 }
 
+static inline unsigned int
+num_act_frames_from_sha_frames(const unsigned int num)
+{
+    /* How many frames are needed for the active grant table,
+     * given the size of the shared grant table?
+     *
+     * act_per_page = PAGE_SIZE / sizeof(active_grant_entry_t);
+     * sha_per_page = PAGE_SIZE / sizeof(grant_entry_t);
+     * num_sha_entries = num * sha_per_page;
+     * num_act_frames = (num_sha_entries + (act_per_page-1)) / act_per_page;
+     */
+    return ((num * (PAGE_SIZE / sizeof(grant_entry_t))) +
+            ((PAGE_SIZE / sizeof(struct active_grant_entry))-1))
+           / (PAGE_SIZE / sizeof(struct active_grant_entry));
+}
+
+static inline unsigned int
+nr_active_grant_frames(struct grant_table *gt)
+{
+    return num_act_frames_from_sha_frames(nr_grant_frames(gt));
+}
+
 #endif /* __XEN_GRANT_TABLE_H__ */